package com.michael.retail.auth.service.impl;

import com.michael.retail.auth.exception.ValidCodeException;
import com.michael.retail.auth.service.ValidCodeService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 类功能描述:
 * <pre>
 *   验证码服务
 * </pre>
 *
 * @author Michael
 * @version 1.0
 * @date 2021/7/12 17:33
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ValidCodeServiceImpl implements ValidCodeService {


    private final RedisTemplate<String, Object> redisTemplate;

    /** 保存验证码到Redis */
    @Override
    public void setServerValidCode(String keyPrefix, String requestId, String validCode, long expireSeconds) {
        redisTemplate.opsForValue().set(
                getValidCodeKey(keyPrefix, requestId),
                validCode,
                expireSeconds,
                TimeUnit.SECONDS
        );
    }

    @Override
    public void validate(String keyPrefix, String requestId, String validCode) {
        if (!StringUtils.hasText(requestId)) {
            throw new ValidCodeException("请在请求参数中携带requestId参数");
        }

        String code = this.getServerValidCode(keyPrefix, requestId);

        if (!StringUtils.hasText(validCode)) {
            throw new ValidCodeException("请填写验证码");
        }

        if (code == null) {
            throw new ValidCodeException("验证码不存在或已过期");
        }

        if (!code.equalsIgnoreCase(validCode.toLowerCase())) {
            throw new ValidCodeException("验证码不正确");
        }

        this.remove(keyPrefix, requestId);
    }

    private void remove(String keyPrefix, String requestId) {
        redisTemplate.delete(getValidCodeKey(keyPrefix, requestId));
    }

    private String getServerValidCode(String keyPrefix, String requestId) {
        return (String) redisTemplate.opsForValue().get(getValidCodeKey(keyPrefix, requestId));
    }

    private String getValidCodeKey(String keyPrefix, String requestId) {
        return keyPrefix + ":" + requestId;
    }
}
